﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using TrinityAPI.Base.Models;

namespace TrinityAPI.Base.Tools
{
    /// <summary>
    /// 异常操作类
    /// </summary>
    public class ExceptionHelper
    {
        public static BaseException GenException(ErrorCode errorCode, params object[] args)
        {
            return GenException("@" + errorCode.ToString(), errorCode, args);
        }

        public static BaseException GenException(string param, params object[] args)
        {
            return GenException(param, ErrorCode.E000000001, args);
        }

        public static BaseException GenException(string param, ErrorCode defaultCode, params object[] args)
        {
            return GenException(param, defaultCode, APIContext.DefaultErrorMessages, APIContext.ErrorMessages, APIContext.Language, args);
        }

        public static BaseException GenException(string param, ErrorCode defaultCode, JObject DefaultErrorMessages, JObject ErrorMessages, string language, params object[] args)
        {
            string code = defaultCode.ToString();
            string message = GetDefaultMessage(defaultCode);
            if (ErrorMessages != null && param != null && param.StartsWith("@"))
            {
                string key = param.TrimStart('@');
                var value = ErrorMessages.GetJsonObjectValue(key);
                GetCodeAndMessage(key, value, language, ref code, ref message);
            }
            else if (DefaultErrorMessages != null && DefaultErrorMessages.ContainsProperty(code))
            {
                var value = DefaultErrorMessages.GetJsonObjectValue(code);
                GetCodeAndMessage(code, value, language, ref code, ref message);
            }
            else if (!string.IsNullOrWhiteSpace(param) && !param.StartsWith("@"))
            {
                message = param;
            }
            if (!string.IsNullOrWhiteSpace(code) && !string.IsNullOrWhiteSpace(message))
                return new BaseException(code, message, args);
            return new BaseException();
        }

        private static string GetDefaultMessage(ErrorCode defaultCode)
        {
            System.Reflection.FieldInfo fi = defaultCode.GetType().GetField(defaultCode.ToString());
            var attribute = Attribute.GetCustomAttribute(fi, typeof(ErrorDescriptionAttribute)) as ErrorDescriptionAttribute;
            if (attribute == null)
                return null;
            return attribute.Message;
        }

        private static void GetCodeAndMessage(string key, JToken value, string language, ref string code, ref string message)
        {
            if (value != null && (value.Type == JTokenType.String || value.Type == JTokenType.Object))
            {
                code = key;
                string cod = null;
                string msg = null;
                if (value.Type == JTokenType.Object)
                {
                    cod = (value as JObject).GetJsonObjectStringValue("code");
                    msg = (value as JObject).GetJsonObjectStringValue(language);
                }
                else
                {
                    msg = value.ToString();
                }
                if (!string.IsNullOrWhiteSpace(cod))
                    code = cod;
                if (!string.IsNullOrWhiteSpace(msg))
                    message = msg;
            }
        }
    }
}
